package sg.edu.nus.iss.billing.vo.subscription;

import java.util.ArrayList;

import sg.edu.nus.iss.billing.common.DbUtil;
import sg.edu.nus.iss.billing.common.Util;
import sg.edu.nus.iss.billing.common.exception.InvalidParamsException;
import sg.edu.nus.iss.billing.vo.subscription.feature.FeatureVO;
import sg.edu.nus.iss.billing.vo.subscription.feature.LocalCallFeatureVO;

public class MobileVoiceVO extends VoiceVO {

	private ArrayList<FeatureVO> optionalFeatures = new ArrayList<FeatureVO>();
	private String phoneNumber;
	private LocalCallFeatureVO localCall = new LocalCallFeatureVO();
	
	public MobileVoiceVO() {
		setAccNo(Util.Default_NULL);
		setSubsId(Util.Default_NULL);
		setName(Util.SUBSCRIPTIONVO_MOBILEVOICE);
		setStartDate(Util.getNullDate());
		setEndDate(Util.getNullDate());
		setMonthlySuscription(0);
		setStatus(Util.ACCOUNT_STATUS_INACTIVE);
		setDescription(Util.Default_NULL);
		setPhoneNumber(Util.generateRandomPhoneNumber());
	}

	@Override
	public void setPhoneNumber(String phoneNumber) {
		this.phoneNumber = phoneNumber;
	}

	@Override
	public String getPhoneNumber() {
		return phoneNumber;
	}

	@Override
	public void setLocalCallFeatureVO(LocalCallFeatureVO localCall) {
		this.localCall = localCall;
	}

	@Override
	public LocalCallFeatureVO getLocalCallFeatureVO() {
		return localCall;
	}

	@Override
	public void addOptionalFeatures(FeatureVO feature) {
		optionalFeatures.add(feature);
	}
	
	public void addOptionalFeatures(ArrayList<FeatureVO> optionalFeatures) {
		this.optionalFeatures=optionalFeatures;
	}

	@Override
	public FeatureVO getOptionalFeature(String featureName) {
		for (int i=0; i<optionalFeatures.size(); i++) {
			if (optionalFeatures.get(i).getName().equals(featureName)) {
				return optionalFeatures.get(i);
			}
		}
		return null;
	}

	@Override
	public ArrayList<FeatureVO> getAllOptionalFeature() {
		return optionalFeatures;
	}

	@Override
	public void setParameters(String serialisedEntry)
			throws InvalidParamsException {
		String[] tokens =  serialisedEntry.split(java.util.regex.Pattern.quote(DbUtil.DELIMITER));
		if (tokens.length <9 ) {
			throw new InvalidParamsException("Expected 9 or more parameters, received " + tokens.length);
		} else {
			setAccNo(tokens[0]);
			setSubsId(tokens[1]);
			setName(tokens[2]);
			setStartDate(Util.getDateFromString(tokens[3]));
			setEndDate(Util.getDateFromString(tokens[4]));
			setMonthlySuscription(Double.parseDouble(tokens[5]));
			setStatus(tokens[6]);
			setDescription(tokens[7]);
			setPhoneNumber(tokens[8]);
			
			StringBuilder sb = new StringBuilder();
			sb.append(tokens[9]);
			sb.append(DbUtil.DELIMITER);
			sb.append(tokens[10]);
			sb.append(DbUtil.DELIMITER);
			sb.append(tokens[11]);
			sb.append(DbUtil.DELIMITER);
			sb.append(tokens[12]);
			sb.append(DbUtil.DELIMITER);
			sb.append(tokens[13]);
			LocalCallFeatureVO localCall = new LocalCallFeatureVO();
			localCall.setParameters(sb.toString());
			setLocalCallFeatureVO(localCall);
			
			// set optional features
			int cnt = Integer.parseInt(tokens[14]);
			int scCnt = 15;
			for (int i=0; i<cnt; i++) {
				StringBuilder sb2 = new StringBuilder();
				sb2.append(tokens[scCnt]);
				sb2.append(DbUtil.DELIMITER);
				sb2.append(tokens[scCnt+1]);
				sb2.append(DbUtil.DELIMITER);
				sb2.append(tokens[scCnt+2]);
				sb2.append(DbUtil.DELIMITER);
				sb2.append(tokens[scCnt+3]);
				sb2.append(DbUtil.DELIMITER);
				sb2.append(tokens[scCnt+4]);

				try {
					FeatureVO feat;
					feat = (FeatureVO) Util.getFeatureVOMap().get(tokens[scCnt]).newInstance();
					feat.setParameters(sb2.toString());
					addOptionalFeatures(feat);
				} catch (InstantiationException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				}
				scCnt+=5;
			}
		}
	}

	@Override
	public String serialised() {
		StringBuilder sb = new StringBuilder();
		sb.append(getAccNo());
		sb.append(DbUtil.DELIMITER);
		sb.append(getSubsId());
		sb.append(DbUtil.DELIMITER);
		sb.append(getName());
		sb.append(DbUtil.DELIMITER);
		sb.append(Util.getFormattedDate(getStartDate()));
		sb.append(DbUtil.DELIMITER);
		sb.append(Util.getFormattedDate(getEndDate()));
		sb.append(DbUtil.DELIMITER);
		sb.append(getMonthlySuscription());
		sb.append(DbUtil.DELIMITER);
		sb.append(getStatus());
		sb.append(DbUtil.DELIMITER);
		sb.append(getDescription());
		sb.append(DbUtil.DELIMITER);
		
		sb.append(getPhoneNumber());
		sb.append(DbUtil.DELIMITER);
		
		sb.append(getLocalCallFeatureVO().serialised());
		sb.append(DbUtil.DELIMITER);
		

		sb.append(optionalFeatures.size());
		for (int i=0; i<optionalFeatures.size(); i++) {
			FeatureVO feat = optionalFeatures.get(i);
			sb.append(DbUtil.DELIMITER);
			sb.append(feat.serialised());
		}
		
		return sb.toString();
	}

	public void clearFeatures() {
		optionalFeatures.clear(); 
		
	}

}
